﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace spec_unsafe.IO
{
    struct Msg
    {
        public UInt32 msg;
        public int a;
        public int b;
        public int c;
        public bool d;
        public unsafe fixed char name[8];
    }
    struct MsgD
    {
        public UInt32 msg;
        public int a;
        public int b;
        public int c;
        public bool d;
        public string name;
    }

    struct Header
    {
        public UInt32 magic;
        public int typeACount;
        public int typeBCount;
        public int typeCCount;
    }
    struct typeA
    {

    }
    struct typeB
    {

    }
    struct typeC
    {

    }
    class FileInfo
    {
        public Header header;
        public typeA[] typea;
        public typeB[] typeb;
        public typeC[] typec;
    }
    class IO
    {
        static byte[] buffer = new byte[32];
        static Msg ReadLikeC(System.IO.Stream stream)
        {
            stream.Read(buffer, 0, 28);
            unsafe
            {
                fixed (byte* bb = buffer)
                {
                    Msg msg = *(Msg*)bb;
                    return msg;
                }
            }
        }

        static MsgD ReadLikeCSharp(System.IO.Stream stream)
        {
            //用某种序列化方法或某种序列化库
            //他们的原理都是one by one 模式
            MsgD msg = new MsgD();
            using (var sr = new System.IO.BinaryReader(stream))
            {
                msg.msg = sr.ReadUInt32();
                msg.a = sr.ReadInt32();
                msg.b = sr.ReadInt32();
                msg.c = sr.ReadInt32();
                msg.d = sr.ReadBoolean();
                msg.name = sr.ReadString();
            }
            return msg;
        }
        static FileInfo ReadFile(System.IO.Stream stream)
        {
            FileInfo info = new FileInfo();
            unsafe
            {
                fixed (byte* bufptr = buffer)
                {
                    stream.Read(buffer, 0, 16);
                    info.header = *(Header*)bufptr;
                    info.typea = new typeA[info.header.typeACount];
                    info.typeb = new typeB[info.header.typeBCount];
                    info.typec = new typeC[info.header.typeCCount];
                    fixed (typeA* ptra = info.typea)
                    {
                        //span是c#的新语法
                        var span = new Span<byte>(ptra, info.header.typeACount);
                        stream.Read(span);
                    }
                    fixed (typeB* ptrb = info.typeb)
                    {
                        var span = new Span<byte>(ptrb, info.header.typeBCount);
                        stream.Read(span);
                    }
                    fixed (typeC* ptrc = info.typec)
                    {
                        var span = new Span<byte>(ptrc, info.header.typeCCount);
                        stream.Read(span);
                    }
                }
            }
            return info;
        }
    }
}
